<template>
	<use-box>
		<div class="dflex menu-manage">
			<!-- 模型机 -->
			<div class="fe-phone">
				<div class="fe-phone-left"></div>
				<div class="fe-phone-center">
					<div class="fe-phone-top"></div>
					<div class="fe-phone-main pos_r">
						<div class="phone-container pos_r sele_none">
							<header>
								<label>又是云</label>
							</header>
							<img class="qrcode pos_a" src="/static/img/official_accounts.jpg">
							<div v-loading="menuLoading" class="loading"></div>
							<vuedraggable :disabled="submitLoading" class="dflex_vertical_c footer"
								v-model="data.button" draggable=".popover">
								<el-popover placement="top" trigger="manual" width="100" popper-class="wx-menu"
									class="popover" :visible-arrow="false" v-for="(item, i) in data.button" :key="i"
									v-model="item.visible">
									<div slot="reference" class="menu" :class="{active: mainId == item.id && !subId}"
										@click="addMainMenu(item, i)"><span
											v-if="item.sub_button && item.sub_button.length"
											class="iconfont icongengduo"></span>{{item.name}}
									</div>
									<vuedraggable :disabled="submitLoading" v-model="item.sub_button"
										class="submenu crpr" draggable=".submenu-item">
										<div v-for="(sub, x) in item.sub_button" :key="x"
											class="padding_lr_10 w100 dflex_c sele_none submenu-item"
											:class="{active: subId == sub.id}" @click="addSubMenu(sub, x)">
											{{sub.name}}
										</div>
										<div v-if="!item.sub_button || item.sub_button.length < 5"
											class="el-icon-plus padding_lr_10 w100 dflex_c" @click="addSubMenu()"></div>
									</vuedraggable>
								</el-popover>
								<div v-if="data.button.length < 3" class="el-icon-plus h100 menu"
									@click="addMainMenu()">
								</div>
							</vuedraggable>
						</div>
					</div>
					<div class="fe-phone-bottom" style="overflow:hidden;">
					</div>
				</div>
				<div class="fe-phone-right"></div>
			</div>
			<!-- form表单 -->
			<div class="add_edit dflex1 margin_l_30 owoy" v-show="formShow">
				<el-form :model="form" :rules="rules" ref="ruleForm" label-width="140px">
					<h3>{{menuName}}</h3>
					<el-form-item label="菜单名称" class="margin_t_20" prop="name" ref="name">
						<el-input :disabled="submitLoading" v-model="form.name" class="menu-name" placeholder="请输入菜单名称"
							:maxlength="menu == '主菜单' ? 5 : 10" show-word-limit clearable
							@blur="nameInputBlur(form.name)">
						</el-input>
						<div v-if="isSubButton" class="remark_txt">
							已添加子菜单，仅可设置菜单名称
						</div>
					</el-form-item>
					<div v-show="!isSubButton">
						<el-form-item label="菜单内容">
							<el-radio-group :disabled="submitLoading" v-model="form.type" @change="typeChange">
								<el-radio label="view">跳转网页</el-radio>
								<el-radio label="miniprogram">跳转小程序</el-radio>
								<el-radio label="click">发送消息</el-radio>
								<el-radio label="scancode_push">扫一扫</el-radio>
							</el-radio-group>
						</el-form-item>
						<el-form-item label="小程序appid" v-show="form.type == 'miniprogram'" prop="appid" ref="appid">
							<el-input :disabled="submitLoading" v-model="form.appid" placeholder="请输入小程序appid">
							</el-input>
							<div class="remark_txt">订阅者点击该菜单会跳到以下小程序</div>
						</el-form-item>
						<el-form-item label="小程序页面路径" v-show="form.type == 'miniprogram'" prop="pagepath"
							ref="pagepath">
							<el-input :disabled="submitLoading" v-model="form.pagepath" placeholder="请输入小程序页面路径">
							</el-input>
						</el-form-item>
						<el-form-item v-show="form.type == 'view' || form.type == 'miniprogram'"
							:label="form.type == 'view' ? '页面地址' : '备用网页'" prop="url" ref="url">
							<el-input :disabled="submitLoading" v-model="form.url" type="textarea"
								:autosize="{ minRows: 4}" :placeholder="form.type == 'view' ? '请输入页面地址' : '请输入备用网页'">
							</el-input>
							<div class="remark_txt" v-show="form.type == 'view'">订阅者点击该菜单会跳到以下链接</div>
							<div class="remark_txt" v-show="form.type == 'miniprogram'">旧版微信客户端无法支持小程序，用户点击菜单时将会打开备用网页
							</div>
						</el-form-item>
						<el-form-item label="网页授权" v-show="form.type == 'view'">
							<el-switch :disabled="submitLoading" v-model="authorization" active-color="#ff6a6c"
								inactive-color="#bbb" @change="createUrl"></el-switch>
						</el-form-item>
						<div v-if="authorization">
							<el-form-item label="授权类型">
								<el-radio-group :disabled="submitLoading" v-model="type" @change="createUrl">
									<el-radio label="snsapi_base">基本授权 snsapi_base</el-radio>
									<el-radio label="snsapi_userinfo">用户授权 snsapi_userinfo</el-radio>
								</el-radio-group>
							</el-form-item>
							<el-form-item label="授权网页">
								<el-input :disabled="submitLoading" v-model="url" @input="createUrl"
									placeholder="请输入页面地址">
								</el-input>
							</el-form-item>
							<el-form-item label="页面参数">
								<el-input :disabled="submitLoading" v-model="state" @input="createUrl"
									placeholder="请输入页面参数"></el-input>
								<div class="remark_txt">重定向后会带上state参数，开发者可以填写a-zA-Z0-9的参数值，最多128字节</div>
							</el-form-item>
						</div>
						<el-form-item v-show="form.type == 'click' || form.type == 'scancode_push'" label="key"
							prop="key" ref="key">
							<el-input :disabled="form.type == 'scancode_push' || submitLoading" v-model="form.key"
								placeholder="请输入消息key">
							</el-input>
						</el-form-item>
					</div>
				</el-form>
			</div>
			<div class="btn pos_a">
				<vuedraggable>
					<el-button :disabled="menuLoading" :loading="submitLoading" class="margin_l_40 submit-btn"
						type="success" round @click="submit('ruleForm')">保存到微信</el-button>
					<el-button v-if="formShow" :disabled="submitLoading" class="return-btn" round icon="el-icon-back"
						@click="deleMenu">删除
					</el-button>
				</vuedraggable>
			</div>
		</div>
	</use-box>
</template>

<script>
	let _this;
	import vuedraggable from 'vuedraggable';
	export default {
		components: {
			vuedraggable
		},
		data() {
			const validateAppid = async (rule, value, callback) => {
				if (this.form.type == 'miniprogram' && !value) {
					return callback(new Error('请输入小程序appid'));
				}

				callback();
			};
			const validatePagepath = async (rule, value, callback) => {
				if (this.form.type == 'miniprogram' && !value) {
					return callback(new Error('请输入小程序页面路径'));
				}

				callback();
			};
			const validateUrl = async (rule, value, callback) => {
				if (this.form.type == 'view' && !value) {
					return callback(new Error('请输入网页地址'));
				} else if (this.form.type == 'miniprogram') {
					if (!value && !this.form.appid && !this.form.pagepath) {
						return callback(new Error('请输入备用网页'));
					}
				}

				callback();
			};
			const validateKey = async (rule, value, callback) => {
				if (this.form.type == 'click' && !value) {
					return callback(new Error('请输入消息key'));
				}

				callback();
			};
			return {
				// 公众号数据
				data: {
					button: []
				},
				// 菜单 loading
				menuLoading: false,
				// 唯一标识id
				idx: 0,
				// 主菜单id
				mainId: 0,
				// 子菜单id
				subId: 0,
				// 主菜单 子菜单
				menu: '',
				// 菜单名称
				menuName: "",
				// form表单显示隐藏
				formShow: false,
				form: {
					name: "",
					type: "view",
					appid: "",
					pagepath: "",
					url: "",
					key: ""
				},
				formOld: {},
				rules: {
					name: [{
						required: true,
						message: '请输入菜单名称',
						trigger: 'change'
					}],
					appid: [{
						required: true,
						validator: validateAppid,
						trigger: 'change'
					}],
					pagepath: [{
						required: true,
						validator: validatePagepath,
						trigger: 'change'
					}],
					url: [{
						required: true,
						validator: validateUrl,
						trigger: 'change'
					}],
					key: [{
						required: true,
						validator: validateKey,
						trigger: 'change'
					}]
				},
				// 网页授权开启关闭
				authorization: false,
				// 授权类型
				type: "snsapi_base",
				// appid
				appid: '',
				// 授权网页
				url: "",
				// 页面参数
				state: "",
				// 同步至微信公众号 loading
				submitLoading: false
			};
		},
		watch: {
			// form 给 data.button 赋值
			form: {
				handler: (newVal, oldVal) => {
					// 获取当前选中主菜单
					let button = _this.data.button.find(x => x.id == _this.mainId);

					// 当前是否选中子菜单
					if (_this.subId) {
						// 获取当前选中子菜单
						let subButton = button.sub_button.find(x => x.id == _this.subId);
						// 赋值给子菜单
						for (const key in newVal) {
							subButton[key] = newVal[key];
						}
					} else {
						// 赋值给主菜单
						for (const key in newVal) {
							button[key] = newVal[key];
						}
					}
				},
				deep: true
			}
		},
		computed: {
			// 是否存在子菜单
			isSubButton() {
				if (this.mainId && !this.subId) {
					let button = this.data.button.find(x => x.id == this.mainId);

					return button.sub_button.length;
				}

				return 0;
			}
		},
		methods: {
			// 请求菜单数据
			loadData() {
				this.menuLoading = true;

				this.$func.wmzadmin
					.call('wx/wxMenuGet', {},
						false
					).then(res => {
						if (res.code == 200) {
							// 修改数据结构，加上唯一标识id
							res.datas.button.forEach(button => {
								button.id = ++this.idx;
								button.visible = false;
								button.sub_button = button.sub_button || [];
								if (button.sub_button.length) {
									button.sub_button.forEach(sub => {
										sub.id = ++this.idx;
									});
								}
							});

							this.appid = res.datas.appid;

							this.data = res.datas;
						}
						this.menuLoading = false;
					});
			},
			// 网页授权 获取 url
			createUrl() {
				this.form.url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${this.appid}&redirect_uri=${encodeURIComponent(
		                this.url
		            )}&response_type=code&scope=${this.type}&state=${
		                this.state
		            }#wechat_redirect`;
			},
			// 添加主菜单
			addMainMenu(menu, i) {
				// 菜单
				this.menu = '主菜单';

				// 给子菜单默认值
				this.subId = 0;

				// 存在主菜单
				if (menu) {
					// 赋值id
					this.mainId = menu.id;

					// 菜单隐藏
					this.data.button.forEach(x => {
						if (x.id != this.mainId) {
							x.visible = false;
						}
					});

					// 赋值form
					this.__set_form(menu);
					// 菜单弹出
					menu.visible = !menu.visible;
					// 赋值菜单名
					this.menuName = menu.name;
				} else {
					// 赋值菜单名
					this.menuName = "主菜单";

					// 添加主菜单
					this.data.button.push({
						id: ++this.idx,
						name: "主菜单",
						visible: false,
						sub_button: []
					});

					// 赋值id
					this.mainId = this.idx;
					// 清除form
					this.__clear_form();

					this.$nextTick(() => {
						// 、菜单开启
						this.data.button.find(x => x.id == this.mainId).visible = true;

						// 赋值form菜单名称
						this.form.name = '主菜单';
					})
				}

				// 开启form
				this.formShow = true;
				// 关闭网页授权
				this.authorization = false;
			},
			// 添加子菜单
			addSubMenu(sub, i) {
				// 菜单
				this.menu = '子菜单';

				// 存在子菜单
				if (sub) {
					// 赋值id
					this.subId = sub.id;
					// 赋值 form
					this.__set_form(sub);
					// 赋值菜单名
					this.menuName = sub.name;
				} else {
					// 赋值菜单名
					this.menuName = "子菜单";
					// 获取主菜单
					let button = this.data.button.find(x => x.id == this.mainId);
					// 菜单隐藏
					button.visible = false;

					// 添加子菜单
					button.sub_button.push({
						id: ++this.idx,
						name: "子菜单"
					});

					// 赋值id
					this.subId = this.idx;
					// 清除form
					this.__clear_form();

					this.$nextTick(() => {
						// 菜单弹出
						button.visible = true;
						// 赋值form菜单名称
						this.form.name = '子菜单';
					})
				}

				// 开启form
				this.formShow = true;
				// 关闭网页授权
				this.authorization = false;
			},
			// 菜单名称失焦
			nameInputBlur(res) {
				// 为空
				if (!res) {
					// 赋值
					this.form.name = this.menu;
				}
			},
			// 菜单内容切换
			typeChange(res) {
				// 跳转网页 或者 跳转小程序 并且 不存在 网页地址
				if ((this.form.type == 'view' || this.form.type == 'miniprogram') && !this.form.url) {
					// 清除表单验证验证
					this.$refs.url.clearValidate();
				}

				if (this.form.type == 'miniprogram' && !this.form.appid) {
					this.$refs.appid.clearValidate();
				}

				if (this.form.type == 'miniprogram' && !this.form.pagepath) {
					this.$refs.pagepath.clearValidate();
				}

				if ((this.form.type == 'click' || this.form.type == 'scancode_push') && !this.form.key) {
					this.$refs.key.clearValidate();
				}

				// 不是跳转网页 网页授权关闭
				if (res != 'view') {
					this.authorization = false;
				}

				// 扫一扫 给默认值
				if (res == 'scancode_push') {
					this.form.key = 'scan';
				} else if (res == 'click') {
					// 发送消息 清空 并且 清除表单验证
					this.form.key = '';
					this.$nextTick(() => {
						this.$refs.key.clearValidate();
					})
				}
			},
			// 删除菜单
			deleMenu() {
				this.$confirm("此操作将删除此菜单, 是否继续?", "提示", {
					confirmButtonText: "确定",
					cancelButtonText: "取消",
					type: "warning"
				}).then(() => {
					// 获取当前选中的主菜单
					let button = this.data.button.find(x => x.id == this.mainId);
					// 获取当前选中的主菜单索引
					let buttonIdx = this.data.button.findIndex(x => x.id == this.mainId);

					// 当前是否选中子菜单
					if (this.subId) {
						// 获取当前选中的子菜单索引
						let subButtonIdx = button.sub_button.findIndex(x => x.id == this.subId);

						// 删除子菜单
						this.data.button[buttonIdx].sub_button.splice(subButtonIdx, 1);

						// 刷新菜单
						this.data.button[buttonIdx].visible = false;

						this.$nextTick(() => {
							this.data.button[buttonIdx].visible = true;
						})
					} else {
						// 删除主菜单
						this.data.button.splice(buttonIdx, 1);
					}

					// 关闭表单
					this.formShow = false;
				});
			},
			// 表单赋值
			__set_form(data) {
				for (const key in data) {
					if (this.form.hasOwnProperty(key)) {
						this.form[key] = data[key];
					}
				}
			},
			// 清除表单
			__clear_form() {
				for (const key in this.formOld) {
					if (this.form.hasOwnProperty(key)) {
						this.form[key] = this.formOld[key];
					}
				}
			},
			// 同步至微信公众号
			async submit(formName) {
				const mainId = this.mainId;
				const subId = this.subId;

				if (!await this.validMenu(formName)) {
					return;
				}

				this.mainId = mainId;
				this.subId = subId;

				// 获取当前选中主菜单
				let button = this.data.button.find(x => x.id == this.mainId);

				// 当前是否选中子菜单
				if (this.subId) {
					// 获取当前选中子菜单
					let subButton = button.sub_button.find(x => x.id == this.subId);
					// 赋值form
					this.__set_form(subButton);
				} else {
					// 赋值form
					this.__set_form(button);
				}

				this.$confirm("此操作将同步微信公众号, 是否继续?", "提示", {
					confirmButtonText: "确定",
					cancelButtonText: "取消",
					type: "warning"
				}).then(() => {
					// 按钮 loading
					this.submitLoading = true;
					this.$func.wmzadmin
						.call('wx/wxMenuPost', {
							button: JSON.stringify(this.data)
						}, false).then(res => {
							if (res.code == 200) {
								this.$message({
									message: "成功同步至微信公众号",
									type: "success"
								});
							}
							this.submitLoading = false;
						})
				});

			},
			// 验证菜单数据
			async validMenu(formName) {
				for (let i = 0; i < this.data.button.length; i++) {
					let button = this.data.button[i];

					this.mainId = button.id;
					if (button.sub_button.length) {
						for (let sIdx = 0; sIdx < button.sub_button.length; sIdx++) {
							let sub = button.sub_button[sIdx];
							// 赋值id
							this.subId = sub.id;
							// 赋值 form
							this.__set_form(sub);

							let res = await this.validForm(formName);
							if (!res) {
								// 菜单隐藏
								this.data.button.forEach(x => {
									x.visible = false;
								});
								// 、菜单开启
								button.visible = true;
								// 赋值菜单名
								this.menuName = sub.name;
								// 开启form
								this.formShow = true;
								return false;
							}
						}
					}
				}

				return true;
			},
			validForm(formName) {
				return new Promise((resolve, reject) => {
					this.$refs[formName].validate((valid, obj) => {
						// 默认获取第一个未验证 form 属性名
						this.$api.set_unvalidated_form_focus(this, obj);

						resolve(valid);
					});
				});
			}
		},
		created() {
			_this = this;

			for (const key in this.form) {
				this.formOld[key] = this.form[key];
			}

			this.loadData();
		}
	};
</script>

<style>
	.menu-manage>>>.el-input,
	.menu-manage>>>.el-textarea {
		width: 70%;
	}

	>>>.el-textarea__inner {
		word-break: break-all;
	}

	.menu-manage>>>.menu-name.el-input {
		width: 30%;
	}

	.menu-manage>>>.menu-name.el-input .el-input__count-inner {
		background-color: #f6f6f6;
	}

	.fe-phone {
		height: 100%;
		min-height: 775px;
		width: 383px;
	}

	.fe-phone-left {
		height: 293px;
		width: 5px;
		background: url("../../static/iphone/phone_left.png") 0px 88px no-repeat;
		float: left;
	}

	.fe-phone-center {
		height: auto;
		width: 372px;
		float: left;
	}

	.fe-phone-top {
		height: 83px;
		width: 372px;
		background: url("../../static/iphone/phone_top.png") 0px 0px no-repeat;
	}

	.fe-phone-main {
		min-height: 610px;
		width: 372px;
		background: url("../../static/iphone/phone_center.png") 0px 0px repeat-y;
		padding: 0px 15px;
		box-sizing: border-box;
	}

	.fe-phone-bottom {
		height: 92px;
		width: 372px;
		background: url("../../static/iphone/phone_bottom.png") 0px 0px no-repeat;
	}

	.fe-phone-right {
		height: 220px;
		width: 6px;
		background: url("../../static/iphone/phone_right.png") 0px 158px no-repeat;
		float: left;
	}

	.phone-container {
		width: 100%;
		height: 100%;
		min-height: 610px;
	}

	.phone-container header {
		height: 64px;
		background: url("../../static/iphone/header.png") no-repeat;
		background-size: cover;
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		text-align: center;
	}

	.phone-container header label {
		color: #e5e5e6;
		font-size: 15px;
		text-align: center;
		position: relative;
		top: 34px;
	}

	.qrcode {
		width: 200px;
		height: 200px;
		left: 50%;
		top: 50%;
		transform: translate(-50%, -50%);
	}

	.loading {
		position: absolute;
		top: 64px;
		left: 0;
		right: 0;
		bottom: 0;
	}

	.phone-container .footer {
		height: 50px;
		position: absolute;
		bottom: 0;
		left: 0;
		right: 0;
		background: #fff;
		border-top: 1px solid #e7e7eb;
	}

	.footer .popover {
		height: 100%;
		flex: 1;
		display: block;
	}

	>>>.el-popover {
		min-width: 100px;
	}

	.footer .menu {
		height: 100%;
		height: 50px;
		font-size: 15px;
		color: #616161;
		text-align: center;
		border-right: 1px solid #e7e7eb;
		cursor: pointer;
		display: flex;
		align-items: center;
		justify-content: center;
		flex: 1;
	}

	.footer .menu:hover {
		border: 1px solid rgba(0, 0, 0, 0.3);
	}

	.footer .menu.active {
		border: 1px solid #000;
	}

	.footer .menu .icongengduo {
		font-size: 14px;
		color: #d1d3d4;
	}

	.submenu {
		width: 100%;
		display: flex;
		align-items: center;
		justify-content: center;
		flex-flow: column;
	}

	.submenu div {
		height: 50px;
		border-bottom: 1px solid #e7e7eb;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
		word-wrap: normal;
	}

	.submenu div:hover {
		border: 1px solid rgba(0, 0, 0, 0.3);
	}

	.submenu div.active {
		border: 1px solid #000;
	}

	.btn {
		bottom: 20px;
		left: 393px;
	}
</style>
